<?php

declare(strict_types=1);

namespace app\common\lib\easywechat;

use liang\MicroEngine;

use EasyWeChat\Factory;
use EasyWeChat\Kernel\Messages\Message;

// 消息处理器
use app\index\handler\OtherHandler;
use app\index\handler\TextMessageHandler;
use app\index\handler\EventMessageHandler;

use app\common\logic\User as UserLogic;
use app\common\logic\Config as ConfigLogic;


/**
 * 公众号
 */
class OfficialAccount
{
    public $app;

    /**
     * 初始化配置
     */
    public function __construct()
    {
        list($appid, $secret) = MicroEngine::getPlatConfig();
        $config = [
            'app_id' => $appid,
            'secret' => $secret,
            // 指定 API 调用返回结果的类型：array(default)/collection/object/raw/自定义类名
            'response_type' => 'array',
        ];
        $this->app = Factory::officialAccount($config);
    }

    // +---------------------------------------------------------------------
    // | 网页授权
    // +---------------------------------------------------------------------
    // | https://easywechat.com/docs/4.x/official-account/oauth
    // +---------------------------------------------------------------------

    /**
     * 调起网页授权
     */
    public function oauth()
    {
        // 当前url
        $url = urlencode(request()->url(true));
        // 回调地址
        $redirect_uri = u('oauth/getUserInfo', ['target_url' => $url]);
        // 调起网页授权页
        $this->app->oauth->scopes(['snsapi_userinfo'])->redirect($redirect_uri)->send();
    }

    /**
     * 获取用户信息存入session
     */
    public function getUserInfo()
    {
        // 获取 OAuth 授权结果用户信息
        $user = $this->app->oauth->user();
        // 原始API返回的结果
        $data = $user->getOriginal();
        // 添加、更新用户
        UserLogic::save($data);
    }

    // +---------------------------------------------------------------------
    // | 消息推送
    // +---------------------------------------------------------------------
    // | https://easywechat.com/docs/4.x/official-account/server
    // +---------------------------------------------------------------------

    /**
     * 消息推送响应微信服务器
     */
    public function response()
    {
        // 访问令牌token
        $token = ConfigLogic::getValueBykey('msg_token');
        //服务器接入验证
        $this->checkSignature($token);
        // 文字消息处理器
        $this->app->server->push(TextMessageHandler::class, Message::TEXT);
        // 事件消息处理器
        $this->app->server->push(EventMessageHandler::class, Message::EVENT);
        // 其他消息处理器
        $this->app->server->push(OtherHandler::class);
        // 响应微信服务器
        return $this->app->server->serve()->send();
    }

    /**
     * 服务器接入验证
     * 开发者服务器接收消息推送
     */
    private function checkSignature(string $token)
    {
        $nonce     = $_GET["nonce"] ?? '';
        $signature = $_GET["signature"] ?? '';
        $timestamp = $_GET["timestamp"] ?? '';
        $tmpArr = array($token, $timestamp, $nonce);
        sort($tmpArr, SORT_STRING);
        $tmpStr = implode('', $tmpArr);
        $tmpStr = trim(sha1($tmpStr));
        if (empty($token)) die('未设置消息推送token令牌');
        if (empty($signature) || empty($tmpStr) || empty($nonce)) die('非法请求！！！');
        if ($tmpStr != $signature) die('签名验证错误');
        isset($_GET['echostr']) ? die($_GET['echostr']) : '';
    }
}
